package com.linkai.JUC._08_pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description: Executors 工具类：3大方法
 *               使用线程池之后，使用线程池来创建线程
 *
 *               线程池的提交优先级和执行优先级：
 *               这个要结合 md 文件的那个图来理解
 *               提交优先级：核心线程 > 队列 > 非核心线程
 *               执行优先级：核心线程 > 非核心线程 > 队列（队列里面的任务要从队列里面出来之后才能执行）
 * @Author: 林凯
 * @Date: 2021/10/25 11:06
 */
public class ThreadPoolDemo01 {
    public static void main(String[] args) {
        /*
            三个方法本质上都还是 new 了一个 ThreadPoolExecutor 对象
            newCachedThreadPool 使用的队列是 SynchronousQueue (同步队列)，等待前一个被消费了，才会去生产第2个
            newSingleThreadExecutor 使用的是 LinkedBlockingQueue（阻塞队列）
            newFixedThreadPool 使用的是 LinkedBlockingQueue（阻塞队列），无参构造的话，容量是 Integer.MAX_VALUE
                所以使用 LinkedBlockingQueue的话，建议指定一个容量，否则可能会造成OOM
                如果是 newCachedThreadPool的话，使用不当可能造成CPU->100%
        * */
        ExecutorService threadPool01 = Executors.newSingleThreadExecutor();// 单个线程
        // 最多只能有5个线程并发执行
        ExecutorService threadPool02 = Executors.newFixedThreadPool(5);    // 创建一个固定的线程池的大小
        ExecutorService threadPool = Executors.newCachedThreadPool();        // 可伸缩的，遇强则前，遇弱则弱

        try {
            for (int i = 0; i < 100; i++) {
                // 通过线程池之后，使用线程池来创建线程
                // 里面传入一个 Runnable 接口，可以使用 Lambda 表达式
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName() + "ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 线程池用完，程序结束
            threadPool.shutdown();
        }


    }
}
